<?php

namespace App\Logics;


use App\Models\Goods;
use App\Models\GoodsDesc;
use App\Models\Order;
use App\Models\OrderAttr;
use App\Models\OrderGoods;
use App\Models\SiteCode;
use App\Models\User;
use Illuminate\Support\Facades\DB;


class OrderLogic extends Logic
{

    // 列表
    // 我的订单
    // 返回列表数据
    public function lists($myUser, $options = [])
    {
        $opt      = $this->option();
        $uid      = $opt->getData('uid', 0, 'intval');
        $keyword  = $opt->getData('keyword', null, 'trim');
        $order_no = $opt->getData('order_no', null, 'trim');
        $page     = $opt->getData('page', 1, 'intval');
        $rows     = $opt->getData('rows', 15, 'intval');
        $mobile   = $opt->getData('mobile', null, 'trim');
        $email    = $opt->getData('email', null, 'trim');

        // 条件
        $map   = [];
        $where = [['status', '>=', 0]];
        if($myUser){
            $map['uid'] = $myUser['id'];
            $where[]    = ['uid', '=', $myUser['id']];
        }
        if($keyword){
            $map     = false;
            $where[] = $opt->orWhere('email|nickname|username|realname', 'like', $keyword);
        }
        if($mobile){
            $map     = false;
            $where[] = $opt->orWhere('mobile', 'like', "%$mobile%");
        }
        if($email){
            $map     = false;
            $where[] = $opt->orWhere('email', 'like', "%$email%");
        }


        // 模型 和 查询
        $model  = new Order();
        $result = $model->listPageCache($map, $where, $page, $rows, "id DESC");
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        // 订单属性，订单商品
        if($result['list']){
            $order_ids  = array_column($result['list'], 'id');
            $orderAttr  = new OrderAttr();
            $orderGoods = new OrderGoods();
            $goodsDb    = new Goods();
            foreach($result['list'] as $key => $item){
                $attr  = $orderAttr->getOneByIdCache($item['id'], '*', 'order_id');
                $goods = $orderGoods->getOneByIdCache($item['id'], '*', 'order_id');
                if(empty($goods)){
                    continue;
                }
                $info = $goodsDb->getOneByIdCache($goods['goods_id'], '*', 'id');
                // 整理
                $result['list'][$key]['attr']         = $attr;
                $result['list'][$key]['goods']        = $info;
                $result['list'][$key]['goods_name']   = $goods['goods_name'] ?? '';
                $result['list'][$key]['goods_number'] = $goods['number'] ?? '';
                $result['list'][$key]['goods_price']  = $goods['price'] ?? '';
                $result['list'][$key]['goods_pic']    = $goods['pic'] ?? '';

                $result['list'][$key]['email']       = $attr['email'] ?? '';
                $result['list'][$key]['card_name']   = $attr['card_name'] ?? '';
                $result['list'][$key]['card_number'] = $attr['card_number'] ?? '';
                $result['list'][$key]['card_date']   = $attr['card_date'] ?? '';
            }
        }

        return $result;
    }

    // 下单
    public function addOrder($myUser, $options = [])
    {
        // 参数
        $opt   = $this->option();
        $goods = $opt->getData('goods', [], 'is_array');  // goods_id number  // 商品信息
        $email = $opt->getData('email', [], 'trim');  // email
        $code  = $opt->getData('code', [], 'trim');  // code

        $data = [
            'uid'         => $myUser['uid'],
            'order_no'    => date('YmdHis').mt_rand(10000, 99999),
            'status'      => 0,
            'email'       => $email ?: $myUser['email'],
            //'money'       => $opt->getData("money", 0, 'floatval'), // 价格
            'address'     => $opt->getData("address", null, 'trim'),
            'mobile'      => $opt->getData("telephone", null, 'trim'),
            'code'        => $opt->getData("code", null, 'trim'),
            'country'     => $opt->getData("areacode", null, 'trim'),  // 国家代码
            'card_name'   => $opt->getData("card_name", null, "trim"),
            'card_number' => $opt->getData("cardnumber", null, "trim"),
            'card_date'   => $opt->getData("time", null, "strtotime"),
            'cvcv'        => $opt->getData("cvvcvc", null, "trim"),
        ];

        // 商品信息
        /*if(count($goods) != count($goods, 1)){
            //return $this->_returnFail('请传递正确商品信息！');.
            return $this->_returnFail('parameter_transmission_error');
        }*/
        // [{goods_id:2, size:small, color:red, number:3, price:2.50 }]
        if(2 == count($goods, 1)){
            //return $this->_returnFail('请传递正确商品信息！');.
            return $this->_returnFail('parameter_transmission_error');
        }

        // 验证码
        $codeDb = new SiteCode();
        $cWhere = [["email", '=', $email], ["ctime", '>=', strtotime("today")], ['status', '=', 0]];
        $lists  = $codeDb->getList($cWhere, 1, 'id DESC');
        if(empty($lists)){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        if($lists[0]['ctime'] + 600 < LARAVEL_TIME){
            return $this->_returnFail('verification_code_timed_out');
            //return $this->_returnFail('验证码超时！');
        }
        if($lists[0]['code'] != $code){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        // 验证码 已经使用
        $codeDb->where('id', $lists[0]['id'])->update(['status' => 1]);


        // 添加
        $userDb   = new User();
        $goodsDb  = new Goods();
        $descDb   = new GoodsDesc();
        $orderDb  = new Order();
        $oGoodsDb = new OrderGoods();
        $oAttrDb  = new OrderAttr();


        // 数据
        $order = $orderDb->filterField($data, true);
        $attr  = $oAttrDb->filterField($data, true);

        // 保存数据
        DB::beginTransaction();
        try{

            // 查询用户信息
            $userInfo = $userDb->lockForUpdate()->where('id', $myUser['id'])->first();
            if(empty($userInfo)){
                throw new \Exception('user_has_no_exist');
                //throw new \Exception('用户不存在！');
                //return $this->_returnFail('用户不存在！');
            }


            // 查询商品信息
            $goodsIds  = array_column($goods, 'goods_id');
            $goods     = array_column($goods, null, 'goods_id');
            $goodsList = $goodsDb->lockForUpdate()->whereIn('id', $goodsIds)->get()->toArray();
            $descList  = $descDb->getListInIdsCache($goodsIds, '*', 'goods_id');
            $money     = 0;  // 商品价格
            $oGoods    = [];

            // TODO 验证商品库存信息
            //  [{goods_id:2, size:small, color:red, number:3, price:2.50 }]
            foreach($goodsList as $_goods){
                // 商品参数
                $_gId   = $_goods['id'];
                $number = $goods[$_gId]['number'] ?? 0;
                if(empty($number)){
                    continue;
                }
                if($number < 0){
                    throw new \Exception('wrong_quantity_of_goods_transmitted');
                    //throw new \Exception('传递商品数量错误！');
                }
                // 验证商品库存
                /*if($number > $_goods['stock']){
                    throw new \Exception('库存不足！');
                }*/
                //$attr_1_name  = $goods[$_gId]['attr_1_name'] ?? '';
                //$attr_2_name  = $goods[$_gId]['attr_2_name'] ?? '';
                $attr_1_value = $goods[$_gId]['attr_1_value'] ?? '';
                $attr_2_value = $goods[$_gId]['attr_2_value'] ?? '';
                $desc_1_name  = $descList[$_gId]['attr_1_name'] ?? '';
                $desc_2_name  = $descList[$_gId]['attr_2_name'] ?? '';
                $desc_1_1     = $descList[$_gId]['attr_1_1'] ?? '';
                $desc_1_2     = $descList[$_gId]['attr_1_2'] ?? '';
                $desc_1_3     = $descList[$_gId]['attr_1_3'] ?? '';
                $desc_2_1     = $descList[$_gId]['attr_2_1'] ?? '';
                $desc_2_2     = $descList[$_gId]['attr_2_2'] ?? '';
                $desc_2_3     = $descList[$_gId]['attr_2_3'] ?? '';
                if($desc_1_name){
                    if($attr_1_value){
                        if(!in_array($attr_1_value, [$desc_1_1, $desc_1_2, $desc_1_3,])){
                            throw new \Exception('transfer_size_does_not_exist');
                            //throw new \Exception('传递的第一个属性不存在！');
                        }
                    } else{
                        throw new \Exception('please_select_size');
                        //throw new \Exception('请选择第一个属性！');
                    }
                } else{
                    if($attr_1_value){
                        throw new \Exception('transfer_size_does_not_exist');
                        //throw new \Exception('传递的第一个属性不存在！');
                    }
                }
                if($desc_2_name){
                    if($attr_2_value){
                        if(!in_array($attr_2_value, [$desc_2_1, $desc_2_2, $desc_2_3,])){
                            throw new \Exception('transfer_size_does_not_exist');
                            //throw new \Exception('传递的第二个属性不存在！');
                        }
                    } else{
                        throw new \Exception('please_select_size');
                        //throw new \Exception('请选择第二个属性！');
                    }
                } else{
                    if($attr_2_value){
                        throw new \Exception('transfer_size_does_not_exist');
                        //throw new \Exception('传递的第二个属性不存在！');
                    }
                }

                // 总价
                $money += $_goods['price'] * $number;

                // 整理
                $oGoods[] = [
                    'order_id'     => 0,
                    'goods_id'     => $_gId,
                    'money'        => $_goods['price'] * $number,
                    'pic'          => $opt->replaceDomain($_goods['pic'], 'old'),
                    'price'        => $_goods['price'],
                    'goods_name'   => $_goods['name'],
                    'number'       => $number,
                    'ctime'        => LARAVEL_TIME,
                    'mtime'        => LARAVEL_TIME,
                    // 商品的属性信息
                    'attr_1_name'  => $desc_1_name,
                    'attr_2_name'  => $desc_2_name,
                    'attr_1_value' => $attr_1_value,
                    'attr_2_value' => $attr_2_value,
                ];

                // 减少商品库存 增加销量  'stock' => DB::raw('stock-'.$number),
                $goodsUpdate = ['sale_no' => DB::raw('sale_no + '.$number),];
                $goodsDb->where('id', $_gId)->update($goodsUpdate);  // ->where('stock', '>=', $number)
            }

            // 添加订单
            $order['money'] = $money;
            $orderDb->fill($order);
            $orderDb->save();
            $oId = $orderDb->id;

            // 附表
            $attr['money']    = $money;
            $attr['order_id'] = $oId;
            $oAttrDb->fill($attr);
            $oAttrDb->save();

            // 订单商品表
            foreach($oGoods as $key => $_item){
                $oGoods[$key]['order_id'] = $oId;
            }
            $oGoodsDb->insert($oGoods);

            // 更新用户信息
            $upUser = [];
            if($data['mobile'] != $myUser['mobile']){
                $upUser['mobile'] = $data['mobile'];
            }
            if($data['address'] != $myUser['address']){
                $upUser['address'] = $data['address'];
            }
            if($data['country'] != $myUser['country']){
                $upUser['country'] = $data['country'];
            }
            if($data['card_name'] != $myUser['card_name']){
                $upUser['card_name'] = $data['card_name'];
            }
            if($data['card_number'] != $myUser['card_number']){
                $upUser['card_number'] = $data['card_number'];
            }
            if($data['card_date'] != $myUser['card_date']){
                $upUser['card_date'] = $data['card_date'];
            }
            if(!empty($upUser)){
                $userDb->where('id', $myUser['id'])->update($upUser);
            }


            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }

        // 缓存操作
        $orderDb->deleteCacheShow($order, $data);
        if(!empty($upUser)){
            $userDb->deleteCacheShow($userInfo);
        }

        return true;
    }


}

